package com.lsh.oms.mis.service.es;

import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.lsh.base.common.exception.BusinessException;
import com.lsh.oms.api.service.es.EsSyncInterface;
import com.lsh.oms.core.constant.EsConstants;
import com.lsh.oms.core.constant.LoggerConstant;
import com.lsh.oms.core.enums.EsOperateType;
import com.lsh.oms.core.enums.EsType;
import com.lsh.oms.core.model.http.HttpMessage;
import com.lsh.oms.core.service.tool.ToolService;
import com.lsh.oms.core.utils.LoggerUtils;
import com.lsh.oms.mis.service.base.EsService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.PostConstruct;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;

/**
 * ElasticSearch Sync Service
 * Created by panxudong on 16/8/26.
 */
@Service(protocol = "dubbo")
public class EsSyncService implements EsSyncInterface {

    private static Logger logger = LoggerFactory.getLogger(EsSyncService.class);

    @Autowired
    private EsService esService;

    @Value("${elasticsearch.oms.ip}")
    private String elasticsearchOmsIp;

    @Value("${elasticsearch.ofc.ip}")
    private String elasticsearchOfcIp;

    @Override
    public String selectIndex(String query, Boolean isCount) {
        String searchUrl = elasticsearchOmsIp + "/oms/order/_search";
        return esService.selectIndex(searchUrl, query, isCount);
    }

    @Override
    public String selectOfcIndex(String query, Boolean isCount) {
        String searchUrl = elasticsearchOfcIp + "/ofc/ofc_so_info/_search";
        return esService.selectIndex(searchUrl, query, isCount);
    }

    @Override
    public <T> Map<String, Map<String, Object>> batchCreateIndex(List<T> orderList) throws Exception {
        return this.batchSaveOrUpdate(orderList, true, EsType.BATCH_CREATE);
    }

    @Override
    public <T> Map<String, Map<String, Object>> batchEditIndex(List<T> orderList) throws Exception {
        return this.batchSaveOrUpdate(orderList, false, EsType.BATCH_EDIT);
    }

    @Override
    public <T> void createIndex(T order) throws Exception {
        this.saveOrUpdate(order, true, EsType.CREATE);
    }

    @Override
    public <T> void editIndex(T order) throws Exception {
        this.saveOrUpdate(order, false, EsType.EDIT);
    }

    @Override
    public <T> void saveOrUpdateIndex(T order) throws Exception {
        this.saveOrUpdate(order, null, EsType.CREATE_OR_EDIT);
    }

    private <T> Map<String, Map<String, Object>> batchSaveOrUpdate(List<T> orderList, boolean isCreate, EsType esType) throws Exception {
        String uuid = UUID.randomUUID().toString();
        String operateType = esType.getDesc();

        LoggerUtils.saveLog(" [" + operateType + " index start][" + uuid + "]", LoggerConstant.LOGGER_INFO);

        Map<String, Map<String, Object>> errorMap;
        try {
            errorMap = esService.batchSaveOrUpdate(orderList, isCreate, uuid, operateType);
        } catch (Exception e) {
            LoggerUtils.saveLog(" [" + operateType + " index error][" + uuid + "][Error message : " + e.getMessage() + "]",
                    LoggerConstant.LOGGER_ERROR);
            throw e;
        }

        LoggerUtils.saveLog(" [" + operateType + " index end][" + uuid + "]", LoggerConstant.LOGGER_INFO);
        return errorMap;
    }

    private <T> void saveOrUpdate(T order, Boolean isCreate, EsType esType) throws Exception {
        String uuid = UUID.randomUUID().toString();
        String operateType = esType.getDesc();

        LoggerUtils.saveLog(" [" + operateType + " index start][" + uuid +
                "][Params : " + JSON.toJSONString(order) + "]", LoggerConstant.LOGGER_INFO);

        Map<String, Object> errorMap = null;
        try {
            if(esType == EsType.CREATE_OR_EDIT) {
                errorMap = esService.saveOrUpdate(order, uuid, operateType);
            } else {
                errorMap = esService.saveOrUpdate(order, isCreate, uuid, operateType);
            }
        } catch (Exception e) {
            LoggerUtils.saveLog(" [" + operateType + " index error][" + uuid + "][Error message : " + e.getMessage() + "]",
                    LoggerConstant.LOGGER_ERROR);
            throw e;
        }

        if(errorMap!=null) {
            if(errorMap.get(EsConstants.ATTR_ERROR) != null) {
                throw (BusinessException)errorMap.get(EsConstants.ATTR_ERROR);
            }
        }

        LoggerUtils.saveLog(" [" + operateType + " index end][" + uuid + "]", LoggerConstant.LOGGER_INFO);
    }

}
